﻿using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;

namespace KC.Service.DTO.Extension
{
    public sealed class RegisterPasswordValidationAttribute : ValidationAttribute, IClientModelValidator
    {
        //public const string Reg = @"^[\w\-\u0100-\u2fff\u3001-\uffff\.\~\!\@\#\$\%\^\&\*\(\)\+\-\=\\\[\]\{\}\|\`]{5,17}$";
        public const string Reg = @"^(?![^a-zA-Z]+$)(?!\D+$).{5,17}$";
        public override bool IsValid(object value)
        {
            if (value == null)
                return true;

            if (value is string)
            {
                var regEx = new Regex(Reg);
                return regEx.IsMatch(value.ToString());
            }
            return false;
        }

        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "registerpassword");
            var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
            MergeAttribute(context.Attributes, "data-val-cannotbered", errorMessage);
        }

        private bool MergeAttribute(
            IDictionary<string, string> attributes,
            string key,
            string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }
            attributes.Add(key, value);
            return true;
        }
    }

    public sealed class ZipCodeValidationAttribute : ValidationAttribute, IClientModelValidator
    {
        public const string Reg = @"^\d{6}$";

        public override bool IsValid(object value)
        {
            if (value == null)
                return true;

            if (value is string)
            {
                var regEx = new Regex(Reg);
                return regEx.IsMatch(value.ToString());
            }
            return false;
        }

        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "zipcode");
            var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
            MergeAttribute(context.Attributes, "data-val-cannotbered", errorMessage);
        }

        private bool MergeAttribute(
            IDictionary<string, string> attributes,
            string key,
            string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }
            attributes.Add(key, value);
            return true;
        }
    }

    public sealed class BusinessLicenseNumberValidationAttribute : ValidationAttribute, IClientModelValidator
    {
        public const string Reg = @"(^\d{15}$)|(^\d{18}$)";

        public override bool IsValid(object value)
        {
            if (value == null)
                return true;

            if (value is string)
            {
                var regEx = new Regex(Reg);
                return regEx.IsMatch(value.ToString());
            }
            return false;
        }

        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "businesslicensenumber");
            var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
            MergeAttribute(context.Attributes, "data-val-cannotbered", errorMessage);
        }

        private bool MergeAttribute(
            IDictionary<string, string> attributes,
            string key,
            string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }
            attributes.Add(key, value);
            return true;
        }
    }

    public sealed class BusinessDateLimitValidationAttribute : ValidationAttribute, IClientModelValidator
    {
        public const string Reg = @"^[1-9][0-9]{0,2}$";

        public override bool IsValid(object value)
        {
            if (value == null)
                return true;

            if (value is int)
            {
                var regEx = new Regex(Reg);
                return regEx.IsMatch(value.ToString());
            }
            return false;
        }

        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "businessdatelimit");
            var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
            MergeAttribute(context.Attributes, "data-val-cannotbered", errorMessage);
        }

        private bool MergeAttribute(
            IDictionary<string, string> attributes,
            string key,
            string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }
            attributes.Add(key, value);
            return true;
        }
    }

    public sealed class RegisteredCapitalValidationAttribute : ValidationAttribute, IClientModelValidator
    {
        public const string Reg = @"^[1-9][0-9]{0,4}(\.\d{1,4})?$";//^[1-9][0-9]{0,4}(\.\d{1,2})?$

        public override bool IsValid(object value)
        {
            if (value == null)
                return true;

            if (value is decimal)
            {
                var regEx = new Regex(Reg);
                return regEx.IsMatch(value.ToString());
            }
            return false;
        }

        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "registeredcapital");
            var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
            MergeAttribute(context.Attributes, "data-val-cannotbered", errorMessage);
        }

        private bool MergeAttribute(
            IDictionary<string, string> attributes,
            string key,
            string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }
            attributes.Add(key, value);
            return true;
        }
    }

    public sealed class OrganizationCodeValidationAttribute : ValidationAttribute, IClientModelValidator
    {
        public const string Reg = @"^[a-zA-Z0-9]{8}-[a-zA-Z0-9]$";

        public override bool IsValid(object value)
        {
            if (value == null)
                return true;

            if (value is string)
            {
                var regEx = new Regex(Reg);
                return regEx.IsMatch(value.ToString());
            }
            return false;
        }

        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "organizationcode");
            var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
            MergeAttribute(context.Attributes, "data-val-cannotbered", errorMessage);
        }

        private bool MergeAttribute(
            IDictionary<string, string> attributes,
            string key,
            string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }
            attributes.Add(key, value);
            return true;
        }
    }

    public sealed class LegalPersonIdentityCardNumberValidationAttribute : ValidationAttribute, IClientModelValidator
    {
        public const string Reg = @"(^\d{15}$)|(^\d{17}([0-9]|X)$)";

        public override bool IsValid(object value)
        {
            if (value == null)
                return true;

            if (value is string)
            {
                var regEx = new Regex(Reg);
                return regEx.IsMatch(value.ToString());
            }
            return false;
        }
        
        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "legalpersonidentitycardnumber");
            var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
            MergeAttribute(context.Attributes, "data-val-cannotbered", errorMessage);
        }

        private bool MergeAttribute(
            IDictionary<string, string> attributes,
            string key,
            string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }
            attributes.Add(key, value);
            return true;
        }
    }

    public sealed class PhoneValidationAttribute : ValidationAttribute, IClientModelValidator
    {
        public const string Reg = @"(^\d{11}$)|^((\d{7,8}$)|(\d{4}|\d{3})-(\d{7,8}$)|(\d{4}|\d{3}$)-(\d{7,8}$)-(\d{4}|\d{3}|\d{2}|\d{1}$)|(\d{7,8}$)-(\d{4}|\d{3}|\d{2}|\d{1})$)";

        public override bool IsValid(object value)
        {
            if (value == null)
                return true;

            if (value is string)
            {
                var regEx = new Regex(Reg);
                return regEx.IsMatch(value.ToString());
            }
            return false;
        }

        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "contactphone");
            var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
            MergeAttribute(context.Attributes, "data-val-cannotbered", errorMessage);
        }

        private bool MergeAttribute(
            IDictionary<string, string> attributes,
            string key,
            string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }
            attributes.Add(key, value);
            return true;
        }
    }

    public sealed class TelephoneValidationAttribute : ValidationAttribute, IClientModelValidator
    {
        public const string Reg = @"(^\d{11}$)|^((\d{7,8}$)|(\d{4}|\d{3})-(\d{7,8}$)|(\d{4}|\d{3}$)-(\d{7,8}$)-(\d{4}|\d{3}|\d{2}|\d{1}$)|(\d{7,8}$)-(\d{4}|\d{3}|\d{2}|\d{1})$)";

        public override bool IsValid(object value)
        {
            if (value == null)
                return true;

            if (value is string)
            {
                var regEx = new Regex(Reg);
                return regEx.IsMatch(value.ToString());
            }
            return false;
        }

        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "telephone");
            var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
            MergeAttribute(context.Attributes, "data-val-cannotbered", errorMessage);
        }

        private bool MergeAttribute(
            IDictionary<string, string> attributes,
            string key,
            string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }
            attributes.Add(key, value);
            return true;
        }
    }

    public sealed class IdentityCardNumberValidationAttribute : ValidationAttribute, IClientModelValidator
    {
        public const string Reg = @"(^\d{15}$)|(^\d{17}([0-9]|X)$)";

        public override bool IsValid(object value)
        {
            if (value == null)
                return true;

            if (value is string)
            {
                var regEx = new Regex(Reg);
                return regEx.IsMatch(value.ToString());
            }
            return false;
        }

        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "identitycardnumber");
            var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
            MergeAttribute(context.Attributes, "data-val-cannotbered", errorMessage);
        }

        private bool MergeAttribute(
            IDictionary<string, string> attributes,
            string key,
            string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }
            attributes.Add(key, value);
            return true;
        }
    }

    public sealed class PositiveFloatNumValidationAttribute : ValidationAttribute, IClientModelValidator
    {
        public override bool IsValid(object value)
        {
            var reg = new Regex(@"^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$");

            return reg.IsMatch(value.ToString());
        }
        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "positivefloatnum");
            var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
            MergeAttribute(context.Attributes, "data-val-cannotbered", errorMessage);
        }

        private bool MergeAttribute(
            IDictionary<string, string> attributes,
            string key,
            string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }
            attributes.Add(key, value);
            return true;
        }
    }
    public sealed class PositiveValidationAttribute : ValidationAttribute, IClientModelValidator
    {
        public override bool IsValid(object value)
        {
            if (value is decimal)
            {
                return (decimal)value > 0;
            }
            return false;
        }

        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "Positive");
            var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
            MergeAttribute(context.Attributes, "data-val-cannotbered", errorMessage);
        }

        private bool MergeAttribute(
            IDictionary<string, string> attributes,
            string key,
            string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }
            attributes.Add(key, value);
            return true;
        }
    }
    public sealed class NonnegativeValidationAttribute : ValidationAttribute, IClientModelValidator
    {
        public override bool IsValid(object value)
        {
            if (value == null)
                return true;

            if (value is decimal)
            {
                return (decimal)value >= 0;
            }
            return false;
        }

        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "Nonnegative");
            var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
            MergeAttribute(context.Attributes, "data-val-cannotbered", errorMessage);
        }

        private bool MergeAttribute(
            IDictionary<string, string> attributes,
            string key,
            string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }
            attributes.Add(key, value);
            return true;
        }
    }
  
}
